/**
 * 版权所有(C)，上海海鼎信息工程股份有限公司，2007，所有权利保留。
 * 
 * 项目名：	rumba
 * 文件名：	TaskScheduleBuffer.java
 * 模块说明：	
 * 修改历史：
 * Nov 11, 2007 - lxm - 创建。
 */
package com.hd123.rumba.sysclock;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.hd123.rumba.exception.BusinessException;
import com.hd123.rumba.option.biz.BOptionCollection;

/**
 * 系统时钟后台任务调度缓冲
 * <p>
 * 
 * 其中的数据来自于有关的消息订阅单，经过加工将被用于后台任务调度，同时该数据将被持久化到数据库中。
 * <p>
 * 
 * 因为该对象本质就是一个BOptionCollection，因此其可以被作为一个选项被保存到数据库中。
 * 
 * @author lxm
 * 
 */
public class TaskScheduleBuffer extends BOptionCollection {

  private static final String PREFIX_NAME_NEXTTIME = "nextTime";
  private static final String SEPERATOR_NAME = ".";
  private static final String REG_SEPERATOR_NAME = "\\.";

  public TaskScheduleBuffer() {
    this.setOptionalClassName(this.getClass().getName());
  }

  /**
   * 取得指定消息订阅单的下一次触发时间。
   * 
   * @param orderUuid
   *          指定消息订阅单的uuid。
   * @return 返回下一次触发时间；若缓冲中不具有相关信息则返回null。
   * @throws BusinessException
   */
  public Date getNextTime(String orderUuid) throws BusinessException {
    if (orderUuid == null)
      throw new BusinessException("必须的参数orderUuid不可为null。");
    String name = PREFIX_NAME_NEXTTIME + SEPERATOR_NAME + orderUuid;
    return (Date) this.values.get(name);
  }

  /**
   * 返回下一次触发时间；若缓冲中不具有相关信息则返回null。
   * 
   * @param orderUuid
   *          指定消息订阅单的uuid。
   * @param nextTime
   *          指定的下次触发时间，不可为null。
   * @throws BusinessException
   */
  public void setNextTime(String orderUuid, Date nextTime) throws BusinessException {
    if (orderUuid == null)
      throw new BusinessException("必须的参数orderUuid不可为null。");
    if (nextTime == null)
      throw new BusinessException("必须的参数nextTime不可为null。");
    String name = PREFIX_NAME_NEXTTIME + SEPERATOR_NAME + orderUuid;
    this.values.put(name, nextTime);
  }

  /**
   * 删除指定消息订阅单的有关信息。
   * 
   * @param orderUuid
   *          指定消息订阅单的uuid。
   * @throws BusinessException
   */
  public void removeOrderInfo(String orderUuid) throws BusinessException {
    if (orderUuid == null)
      throw new BusinessException("必须的参数orderUuid不可为null。");
    String name = PREFIX_NAME_NEXTTIME + SEPERATOR_NAME + orderUuid;
    this.values.remove(name);
  }

  /**
   * 取得缓冲中最早的下次触发时间。
   * 
   * @return 若缓冲中没有数据，则返回null。
   * @throws BusinessException
   */
  public Date getEarliestNextTime() throws BusinessException {
    Date earliestNextTime = null;
    for (String name : this.getNames(PREFIX_NAME_NEXTTIME + SEPERATOR_NAME)) {
      Date nextTime = (Date) this.values.get(name);
      if (earliestNextTime == null || earliestNextTime.after(nextTime))
        earliestNextTime = nextTime;
    }
    return earliestNextTime;
  }

  /**
   * 取得缓冲中最早的下次触发时间。
   * 
   * @param afterTime
   *          要求返回的时间必须晚于该时间。
   * @return 若缓冲中没有符合条件的数据，则返回null。
   * @throws BusinessException
   */
  public Date getEarliestNextTime(Date afterTime) throws BusinessException {
    if (afterTime == null)
      throw new BusinessException("指定的参数afterTime不可为null。");
    Date earliestNextTime = null;
    for (String name : this.getNames(PREFIX_NAME_NEXTTIME + SEPERATOR_NAME)) {
      Date nextTime = (Date) this.values.get(name);
      assert nextTime != null;
      if (nextTime.before(afterTime))
        continue;
      if (earliestNextTime == null || earliestNextTime.after(nextTime))
        earliestNextTime = nextTime;
    }
    return earliestNextTime;
  }

  /**
   * 取得所有具有数据的消息订阅单的uuid。
   * 
   * @return 若缓冲为空，则将返回空的列表。
   * @throws BusinessException
   */
  public List<String> getOrderUuids() throws BusinessException {
    List<String> ret = new ArrayList<String>();
    for (String name : this.getNames(PREFIX_NAME_NEXTTIME + SEPERATOR_NAME)) {
      String[] ss = name.split(REG_SEPERATOR_NAME);
      if (ss.length < 2)
        continue;
      ret.add(ss[1]);
    }
    return ret;
  }
}
